home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- //
- // Sample Windows Communications Program for Doctor Dobb's Journal
- //
- // WINCOM.C - Written by Mike Sax for Dr. Dobb's Journal
- //
- // This file contains a small communications program and uses the terminal
- // window control and xmodem file transfer functions.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- #include <windows.h>
- #include "wincom.h"
- #include "terminal.h"
- #include "comm.h"
- #include "xmodem.h"
-
- // Global variables:
- HWND static ghMainWindow; // The handle of our main window
- HANDLE static ghInstance; // The instance handle of our application
- HICON static ghIcon; // The handle of the main icon
- char static *gszClass = "wincom"; // The class name of our main window
- int static gnPortID; // The current port ID (<0 if none)
- int static gnPortNum; // The current port number (1=COM1)
- static char gszFilename[81]; // Used for XModem transfers
- struct // Used to fill in the combo-boxes
- {
- WORD wID; // ID of the combo box
- char *szText; // String that we should add
- } static gaInitTable[] =
- {
- IDD_COMBOPORT, "COM1:", IDD_COMBOPORT, "COM2:",
- IDD_COMBOPORT, "COM3:", IDD_COMBOPORT, "COM4:",
- IDD_COMBOBAUD, "300", IDD_COMBOBAUD, "1200",
- IDD_COMBOBAUD, "2400", IDD_COMBOBAUD, "4800",
- IDD_COMBOBAUD, "9600", IDD_COMBOBAUD, "19200",
- IDD_COMBOSETTINGS, "N-8-1", IDD_COMBOSETTINGS, "E-7-1",
- IDD_COMBOSETTINGS, "O-7-1", IDD_COMBOSETTINGS, "M-7-1",
- IDD_COMBOSETTINGS, "S-7-1", IDD_COMBOHANDSHAKING, "None",
- IDD_COMBOHANDSHAKING, "XOn/XOff", IDD_COMBOHANDSHAKING, "Hardware",
- 0, NULL
- };
- int static ganBaud[] = { 300, 1200, 2400, 4800, 9600, 19200 };
-
- // Static functions:
- static void Status(char *szText);
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine,
- int nCmdShow);
- static BOOL InitInstance(int nCmdShow);
- static BOOL InitModule(void);
- static BOOL DoEvents(void);
-
- // Exported functions:
- BOOL FAR PASCAL _export InputDlgProc(HANDLE hDlg, WORD wMessage, WORD wParam,
- DWORD lParam);
- BOOL FAR PASCAL _export MainDlgProc(HANDLE hDlg, WORD wMessage, WORD wParam,
- DWORD lParam);
-
- // DoEvents is a function in our program that processes all messages
- // in the message queue and returns FALSE if a WM_QUIT message was
- // received. It also handles dialog box messages for our main window.
- static BOOL DoEvents(void)
- {
- MSG msg;
-
- // Process messages until the message queue is empty or we we have
- // to quit
- while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
- {
- if (msg.message == WM_QUIT)
- {
- PostQuitMessage(msg.wParam);
- return FALSE;
- }
- // IsDialogMessage processes the message if it was meant for
- // our main window (which is a modeless dialog box).
- if (!IsDialogMessage(ghMainWindow, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return TRUE;
- }
-
- // InitApplication is called only once, even if multiple instances of our
- // program are running. Returns TRUE if succes, FALSE if failure
- static BOOL InitModule(void)
- {
- WNDCLASS wc;
-
- wc.style = 0;
- wc.lpfnWndProc = DefDlgProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = DLGWINDOWEXTRA;
- wc.hInstance = ghInstance;
- wc.hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(1));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "DDJCOM";
- return RegisterClass(&wc);
- }
-
- // InitInstance is called once for every instance of our applications. It
- // creates the main window. Returns TRUE if succes, FALSE if failure
- static BOOL InitInstance(int nCmdShow)
- {
- if (!InitTerminal(ghInstance))
- return FALSE;
- ghMainWindow = CreateDialog(ghInstance, MAKEINTRESOURCE(1), NULL,
- MakeProcInstance((FARPROC)MainDlgProc, ghInstance));
- if (!ghMainWindow)
- return FALSE;
- ShowWindow(ghMainWindow, nCmdShow);
- ghIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(1));
- return TRUE;
- }
-
- // WinMain is the first C function that is called in our program. It's
- // the equivalent of main() in non-windows C programs.
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine,
- int nCmdShow)
- {
- ghInstance = hInstance;
-
- if( !hPrevInstance )
- if (!InitModule())
- return 0;
- if (!InitInstance(nCmdShow))
- return 0;
- gnPortNum = 1;
- gnPortID = OpenComPort(gnPortNum);
- if (gnPortID < 0)
- Status("ERROR: Cannot open port COM1:");
- else
- SetComPortParameters(gnPortID, 2400, 'N', 8, 1, FALSE, FALSE);
-
- // This is our main message loop. The DoEvents function processes
- // messages and gives control to other windows. If we have nothing
- // else to do, we process character from the current comm. port.
- while(DoEvents())
- {
- int nChar;
-
- nChar = ComReadChar(gnPortID);
- while(nChar >= 0)
- {
- SendDlgItemMessage(ghMainWindow, IDD_TERMINAL, TW_SENDCHAR,
- nChar, 0l);
- nChar = ComReadChar(gnPortID);
- }
- }
- if (gnPortID >= 0)
- CloseComPort(gnPortID);
- return 0;
- }
-
- // This is the dialog-function of our main window. The main window is a
- // modeless dialog box with its own class.
- BOOL FAR PASCAL _export MainDlgProc(HANDLE hDlg, WORD wMessage, WORD wParam,
- DWORD lParam)
- {
- switch(wMessage)
- {
- case WM_INITDIALOG:
- {
- int i;
-
- // Fill in the combo boxes in our main window
- for(i = 0 ; gaInitTable[i].wID ; ++i)
- SendDlgItemMessage(hDlg, gaInitTable[i].wID, CB_ADDSTRING, 0,
- (long)(LPSTR)gaInitTable[i].szText);
- SendDlgItemMessage(hDlg, IDD_COMBOPORT, CB_SETCURSEL, 0, 0l);
- SendDlgItemMessage(hDlg, IDD_COMBOBAUD, CB_SETCURSEL, 2, 0l);
- SendDlgItemMessage(hDlg, IDD_COMBOSETTINGS, CB_SETCURSEL, 0, 0l);
- SendDlgItemMessage(hDlg, IDD_COMBOHANDSHAKING, CB_SETCURSEL, 0,
- 0l);
- return TRUE;
- }
- case WM_SIZE:
- {
- RECT rectTerminal, rectStatus, rectDialog;
- int cyStatus, cxDialog, cyDialog;
- POINT ptClientOrigin;
-
- GetWindowRect(GetDlgItem(hDlg, IDD_TERMINAL), &rectTerminal);
- GetWindowRect(GetDlgItem(hDlg, IDD_TEXTSTATUS), &rectStatus);
- GetClientRect(hDlg, &rectDialog);
- // Make all rectangles relative to the dialog window
- ptClientOrigin.x = ptClientOrigin.y = 0;
- ClientToScreen(hDlg, &ptClientOrigin);
- OffsetRect(&rectTerminal, -ptClientOrigin.x, -ptClientOrigin.y);
- OffsetRect(&rectStatus, -ptClientOrigin.x, -ptClientOrigin.y);
- cyStatus = rectStatus.bottom - rectStatus.top;
- cxDialog = rectDialog.right - rectDialog.left;
- cyDialog = rectDialog.bottom - rectDialog.top;
- MoveWindow(GetDlgItem(hDlg, IDD_TERMINAL), 0, rectTerminal.top,
- cxDialog, cyDialog - rectTerminal.top - cyStatus, TRUE);
- MoveWindow(GetDlgItem(hDlg, IDD_TEXTSTATUS), 0,
- cyDialog - cyStatus, cxDialog, cyStatus, TRUE);
- }
- break;
- case WM_COMMAND:
- switch(wParam)
- {
- case IDOK: // User pressed Enter
- case IDCANCEL: // User pressed Escape
- SetFocus(GetDlgItem(hDlg, IDD_TERMINAL));
- break;
- case IDM_CLEAR:
- // Clear screen by sending a clear screen to the terminal
- SendDlgItemMessage(hDlg, IDD_TERMINAL, TW_SENDCHAR,
- 12, 0l);
- break;
- case IDM_DOWNLOAD:
- case IDM_UPLOAD:
- {
- FARPROC lpInputProc;
- int bSuccess = FALSE;
-
- if ((lpInputProc = MakeProcInstance((FARPROC)InputDlgProc,
- ghInstance)) != (FARPROC) NULL)
- {
- if (DialogBox(ghInstance, MAKEINTRESOURCE(2), hDlg,
- lpInputProc))
- {
- bSuccess = (wParam == IDM_DOWNLOAD) ?
- DownloadXModem(hDlg, gnPortID, gszFilename) :
- UploadXModem(hDlg, gnPortID, gszFilename);
- }
- FreeProcInstance(lpInputProc);
- }
- Status (bSuccess ? "File transfer successful." :
- "File transfer aborted.");
- }
- break;
- case IDD_COMBOPORT:
- {
- int nNewPort = (int)SendDlgItemMessage(hDlg,
- IDD_COMBOPORT, CB_GETCURSEL, 0, 0l) + 1;
- if (HIWORD(lParam) != CBN_SELCHANGE)
- break;
-
- if (nNewPort != gnPortNum)
- {
- // Close the old port if it was opened
- if (gnPortID >= 0)
- CloseComPort(gnPortID);
- gnPortNum = nNewPort;
- gnPortID = OpenComPort(nNewPort);
- Status((gnPortID >= 0) ? "Port opened" :
- "Error: Cannot open communcations port.");
- }
- SetFocus(GetDlgItem(hDlg, IDD_TERMINAL));
- }
- break;
- case IDD_COMBOBAUD:
- case IDD_COMBOSETTINGS:
- case IDD_COMBOHANDSHAKING:
- {
- char szScrap[10];
- int nBaud;
- int nHandShaking;
-
- if (HIWORD(lParam) != CBN_SELCHANGE)
- break;
- nBaud = ganBaud[SendDlgItemMessage(hDlg, IDD_COMBOBAUD,
- CB_GETCURSEL, 0, 0l)];
- nHandShaking = SendDlgItemMessage(hDlg,
- IDD_COMBOHANDSHAKING, CB_GETCURSEL, 0, 0l);
- SendDlgItemMessage(hDlg, IDD_COMBOSETTINGS, CB_GETLBTEXT,
- (int)SendDlgItemMessage(hDlg,
- IDD_COMBOSETTINGS, CB_GETCURSEL, 0, 0l),
- (long)(LPSTR)szScrap);
- Status((SetComPortParameters(gnPortID, nBaud, szScrap[0],
- szScrap[2] - '0', szScrap[4] - '0',
- nHandShaking == 1, nHandShaking == 2)) ? "" :
- "ERROR: Cannot set communications parameters");
- SetFocus(GetDlgItem(hDlg, IDD_TERMINAL));
- }
- break;
- case IDD_TERMINAL:
- SendDlgItemMessage(ghMainWindow, IDD_TERMINAL,
- TW_SENDCHAR, HIWORD(lParam), 0l);
- ComWriteChar(gnPortID, HIWORD(lParam));
- break;
- case IDM_EXIT:
- PostMessage(hDlg, WM_CLOSE, 0, 0l);
- break;
- default:
- return FALSE;
- }
- break;
- case WM_CLOSE:
- DestroyWindow(hDlg);
- PostQuitMessage(0);
- break;
- default:
- // We didn't process this message, so let Windows do it
- return FALSE;
- }
- return TRUE; // Don't process the message: we already did
- }
-
- // Show a message in the status bar
- static void Status(char *szText)
- {
- SetDlgItemText(ghMainWindow, IDD_TEXTSTATUS, szText);
- }
-
- // This is the dialog box function of the dialog box that is used to get
- // the filename to transfer
- BOOL FAR PASCAL _export InputDlgProc(HANDLE hDlg, WORD wMessage, WORD wParam,
- DWORD lParam)
- {
- switch(wMessage)
- {
- case WM_COMMAND:
- if ((wParam == IDOK) || (wParam == IDCANCEL))
- {
- GetDlgItemText(hDlg, IDD_FILENAME, gszFilename,
- sizeof(gszFilename) - 1);
- EndDialog(hDlg, wParam == IDOK);
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
-